package data_structure.mooc.filereader;

import data_structure.implement.Map;

public class LinkedListMap<K,V>implements Map<K, V> {


    class Node{
        private K key;
        private V value;
        Node next;

        public Node(K key,V value,Node next){

            this.key = key;
            this.value = value;
            this.next=next;
        }
        public Node(K key){
            this(key,null, null);
        }
        public Node (){
            this(null,null,null);
        }

        @Override
        public String toString() {
           return key.toString ()+":"+value.toString ();
        }
    }

    private Node dummyHead;
    private int size;

    public LinkedListMap(){
        dummyHead=new Node();
        size=0;
    }

    /**
     * 返回key所在的节点
     * @param key
     * @return
     */
    private Node getNode(K key){
        Node curr=dummyHead.next;
        while(curr!=null){
            if(curr.key.equals (key))return curr;
            curr=curr.next;
        }
        return null;
    }

    /**
     * 在链表头部添加新的节点
     * @param key
     * @param value
     */
    @Override
    public void add(K key, V value) {
        Node node=getNode (key);
        if(node==null){
            dummyHead.next=new Node (key,value,dummyHead.next);
            size++;
            return;
        }
        node.value=value;
    }

    @Override
    public V remove(K key) {

        Node prev=dummyHead;
        while(prev.next != null){
            if(prev.next.key.equals(key)){
                break;
            }
            prev = prev.next;
        }
        if(prev.next != null){
            Node delNode=prev.next;
            prev.next=delNode.next;
            delNode.next=null;
            size--;
            return delNode.value;
        }
        return null;
    }

    @Override
    public boolean contains(K key) {
        return getNode (key)!=null;
    }

    @Override
    public void set(K key, V newValue) {
        Node node=getNode(key);
        if(node==null){
            throw new IllegalArgumentException (key+"doesn't exit!");
        }
        node.value=newValue;
    }

    @Override
    public V get(K key) {
        if(getNode (key)==null){
            return null;
        }else{
            return getNode(key).value;
        }
    }

    @Override
    public int getSize() {
        return size;
    }

    @Override
    public boolean isEmpty() {
        return size==0;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append ("map:[");
        Node curr=dummyHead.next;
        while(curr != null){
            sb.append (curr.toString ());
            if(curr.next != null){
                sb.append (",");
            }
            curr=curr.next;
        }
        sb.append ("]");
        return sb.toString();
    }

}
